package com.glsc.ngateway.opmanage.service.task;

import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.common.base.domain.mysql.opmanagemain.task.TaskInfo;
import com.glsc.ngateway.common.base.domain.mysql.opmanagemain.task.TaskInfoConfig;
import com.glsc.ngateway.common.base.repo.mysql.opmanagemain.task.TaskInfoConfigRepository;
import com.glsc.ngateway.common.base.repo.mysql.opmanagemain.task.TaskInfoRepository;
import com.glsc.ngateway.opmanage.utils.DateUtils;
import com.glsc.ngateway.opmanage.utils.SpecificationUtil;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;

@Service
public class TaskInfoService {

    @Resource
    private TaskInfoRepository taskInfoRepository;

    @Resource
    private TaskInfoConfigRepository taskInfoConfigRepository;


    /**
     * 根据角色编码查询待办任务列表
     *
     * @param pageNo
     * @param pageSize
     * @param param
     * @param queryType 1系统待办，2订阅待办
     * @return
     */
    public Page<TaskInfo> listByRoleCodes(int pageNo, int pageSize, Map<String, Object> param, Set<String> roleCodes, String queryType) {
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "createTime";
        //只查询待办的任务列表
        param.put("EQ_status", "0");
        if (StringUtils.isBlank(queryType) || "1".equals(queryType)) {
            param.put("INSTR_roleCode", StringUtils.join(roleCodes, ","));
        }

        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);

        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, direction, sort);
        Page<TaskInfo> page = taskInfoRepository.findAll(SpecificationUtil.buildSpecification(param, TaskInfo.class), pageable);
        return page;
    }

    /**
     * 手动点击完成待办任务
     *
     * @param id
     */
    public void finishTaskInfo(Integer id) {
        Optional<TaskInfo> optional = taskInfoRepository.findById(id);
        if (optional.isPresent()) {
            TaskInfo taskInfo = optional.get();
            taskInfo.setStatus("1");
            taskInfo.setFinishTime(new Date());
            taskInfoRepository.save(taskInfo);
        }
    }

    /**
     * 根绝业务id和业务类型自动完成待办任务
     *
     * @param businessId
     * @param type
     */
    public void finishTaskByBusinessIdAndType(String businessId, String type) {
        TaskInfo taskInfo = findByBusinessIdAndType(businessId, type);
        if (Objects.nonNull(taskInfo)) {
            taskInfo.setStatus("1");
            taskInfo.setFinishTime(new Date());
            taskInfoRepository.save(taskInfo);
        }
    }

    /**
     * 根据业务id和业务类型获取待办任务信息
     *
     * @param businessId
     * @param type
     * @return
     */
    public TaskInfo findByBusinessIdAndType(String businessId, String type) {
        List<TaskInfo> list = taskInfoRepository.findAll(Example.of(TaskInfo.builder().businessId(businessId).type(type).status("0").build()));
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 创建待办任务-同一个业务id和业务类型的状态为0的待办任务只能存在一个
     *
     * @param businessId
     * @param name
     * @param roleCode
     * @param shotUrl
     * @param type
     * @return
     */
    public TaskInfo create(String businessId, String name, String roleCode, String shotUrl, String type) {
        TaskInfo existTaskInfo = findByBusinessIdAndType(businessId, type);
        if (Objects.isNull(existTaskInfo)) {
            return taskInfoRepository.save(TaskInfo.builder().businessId(businessId).createTime(new Date()).finishTime(null)
                    .name(name).roleCode(roleCode).shotUrl(shotUrl).status("0").type(type).build());
        }
        return null;
    }


    /**
     * 分页查询我的订阅配置列表
     *
     * @param pageNo
     * @param pageSize
     * @param param
     * @return
     */
    public Page<TaskInfoConfig> listMyTaskConfigPage(int pageNo, int pageSize, Map<String, Object> param) {
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "createTime";

        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);

        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, direction, sort);
        Page<TaskInfoConfig> page = taskInfoConfigRepository.findAll(SpecificationUtil.buildSpecification(param, TaskInfoConfig.class), pageable);
        return page;
    }

    /**
     * 保存待办订阅配置
     *
     * @param taskInfoConfig
     * @return
     */
    public TaskInfoConfig saveConfig(TaskInfoConfig taskInfoConfig) {
        if (Objects.isNull(taskInfoConfig)) {
            return null;
        }
        return taskInfoConfigRepository.save(taskInfoConfig);
    }

    /**
     * 保存待办任务信息
     *
     * @param taskInfo
     * @return
     */
    public TaskInfo saveTaskInfo(TaskInfo taskInfo) {
        if (Objects.isNull(taskInfo)) {
            return null;
        }
        return taskInfoRepository.save(taskInfo);
    }

    /**
     * 根据id删除待办订阅配置
     *
     * @param id
     */
    public void deleteConfig(Integer id) {
        taskInfoConfigRepository.deleteById(id);
    }

    /**
     * 定时任务执行入口，每天凌晨一点执行
     */
    @XxlJob("taskInfoService_dealTask")
    public void dealTask() {
        //查找所有启用状态的待办任务配置
        List<TaskInfoConfig> list = taskInfoConfigRepository.findAll(Example.of(TaskInfoConfig.builder().status("Y").build()));
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<TaskInfo> addList = Lists.newArrayList();
        //获取当前日期
        String currentDate = DateUtils.getCurrentDate(DateUtils.formatDate_);

        for (TaskInfoConfig taskInfoConfig : list) {
            if (StringUtils.isBlank(taskInfoConfig.getExecuteTime())) {
                continue;
            }

            String[] dates = taskInfoConfig.getExecuteTime().split(",");
            if (Objects.isNull(dates) || dates.length == 0) {
                return;
            }

            List<String> dateList = Arrays.asList(dates);

            if (taskInfoConfig.getExecuteType().equals("week")) {
                //每周指定日期执行
                DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
                if (dateList.contains(dayOfWeek.toString())) {
                    addList.add(TaskInfo.builder().type(taskInfoConfig.getType()).status("0").name(taskInfoConfig.getName())
                            .createTime(new Date()).userId(taskInfoConfig.getUserId()).build());
                }
            } else if (taskInfoConfig.getExecuteType().equals("month")) {
                //每月指定日期执行
                for (String day : dateList) {
                    if (currentDate.equals(currentDate.substring(0, 8) + day)) {
                        //
                        addList.add(TaskInfo.builder().type(taskInfoConfig.getType()).status("0").name(taskInfoConfig.getName())
                                .createTime(new Date()).userId(taskInfoConfig.getUserId()).build());
                        break;
                    }
                }

            } else if (taskInfoConfig.getExecuteType().equals("year")) {
                //每年指定日期执行
                if (dateList.contains(currentDate)) {
                    addList.add(TaskInfo.builder().type(taskInfoConfig.getType()).status("0").name(taskInfoConfig.getName())
                            .createTime(new Date()).userId(taskInfoConfig.getUserId()).build());
                }
            } else if (taskInfoConfig.getExecuteType().equals("free")) {
                //自定义的执行日期
                if (dateList.contains(currentDate)) {
                    addList.add(TaskInfo.builder().type(taskInfoConfig.getType()).status("0").name(taskInfoConfig.getName())
                            .createTime(new Date()).userId(taskInfoConfig.getUserId()).build());
                }
            }
        }

        if (CollectionUtils.isNotEmpty(addList)) {
            taskInfoRepository.saveAll(addList);
        }
    }


}
